1 module core.stdc..string;
2 
3 extern(C) extern @nogc nothrow pure
4 {
5     version(WebAssembly) version = CustomDefinitions;
6 
7 
8     version(WebAssembly) version = CustomRuntime;
9     version(PSVita) version = CustomRuntime;
10     version(CustomRuntimeTest) version = CustomRuntime;
11     
12 
13     version(CustomRuntime)
14     {
15         public import object: memcpy, memset, memcmp, memmove;
16     }
17     else
18     {
19         void* memcpy(void* dest, const(void*) src, size_t n);
20         void* memset(void* str, int c, size_t n);
21         int memcmp(const(void*) str1, const(void*) str2, size_t n) pure;
22         void* memmove(return scope void* s1, scope const void* s2, size_t n) pure;
23         const(char)* strchr(const(char)* str, char c) pure @nogc nothrow @trustred;
24     }
25 
26     version(CustomDefinitions)
27     {
28         size_t strlen(const(char)* str) pure @nogc nothrow @trusted
29         {
30             enum ulong mask = 0x8080808080808080; // Mask to check the highest bit of each byte
31             enum ulong magic = 0x0101010101010101; // Magic number to propagate carry
32             size_t* ptr = cast(size_t*)str;
33 
34             size_t len = 0;
35             while(true)
36             {
37                 // Step 2: Check for 0x00 bytes
38                 // If a byte is 0x00, the highest bit of (value - magic) will be 1
39                 ulong value = *ptr;
40                 if(((value - magic) & ~value & mask) != 0)
41                     break;
42                 ptr++;
43                 len+= 8;
44             }
45             while(str[len++] != '\0'){}
46 
47             return len;
48         }
49 
50         const(char)* strchr(const(char)* str, char c) pure @nogc nothrow @trusted
51         {
52             enum ulong mask  = 0x8080808080808080;
53             enum ulong magic = 0x0101010101010101;
54             ulong cc = cast(ubyte)c;
55             cc |= cc << 8;
56             cc |= cc << 16;
57             cc |= cc << 32;
58 
59             auto ptr = cast(const(ulong)*)str;
60             size_t offset = 0;
61 
62             for(;; ptr++, offset += 8)
63             {
64                 ulong value = *ptr;
65 
66                 // detect match with c
67                 ulong diff = value ^ cc;
68                 if(((diff - magic) & ~diff & mask) != 0)
69                     break;
70 
71                 // detect null terminator
72                 if(((value - magic) & ~value & mask) != 0)
73                     break;
74             }
75 
76             // refine, byte by byte
77             for(;; offset++)
78             {
79                 if(str[offset] == c)
80                     return str + offset;
81                 if(str[offset] == '\0')
82                     return null;
83             }
84         }
85 
86 
87         const(char)* strerror(int errnum){return errnum == 0 ? "Success" : "Error";}
88     }
89     else
90     {
91         const(char)* strerror(int errnum);
92         size_t strlen(const(char*) str) pure;
93     }
94 
95     int strncmp (const(char)* str1, const(char)* str2, size_t num );
96     int strcmp (const char* str1, const char* str2);
97     char *strstr(const char *haystack, const char *needle);
98     char* strcpy(char* destination, const char* source);
99 
100 
101 
102     version(PSVita)
103     {
104         int strerror_r(int errnum, scope char* buf, size_t buflen);
105     }
106 }